﻿// -----------------------------------------------------------------------
// <copyright file="SinglePartContent.cs" company="Zen Design Corp">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Zen.BlackBerry.Common
{
	using System;
	using System.IO;
	using System.Net;

	/// <summary>
	/// Abstract class that represents single part message content.
	/// </summary>
	public abstract class SinglePartContent : Content
	{
		/// <summary>
		/// Writes this instance to the specified <see cref="StreamWriter"/>.
		/// </summary>
		/// <param name="writer">The writer.</param>
		public override void WriteTo(StreamWriter writer)
		{
			WriteHeadersTo(writer);
			writer.WriteLine();
			WriteContentTo(writer);
		}

		/// <summary>
		/// Checks the extension.
		/// </summary>
		/// <param name="fileExtension">The file extension.</param>
		protected abstract void CheckExtension(string fileExtension);

		/// <summary>
		/// Gets the bytes from file.
		/// </summary>
		/// <param name="filePath">The file path.</param>
		/// <returns></returns>
		protected byte[] GetBytesFromFile(string filePath)
		{
			// Check file extension is valid for this reader
			CheckExtension(Path.GetExtension(filePath));

			using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
			{
				if(stream.Length > 6000)
				{
					throw new InvalidOperationException("Content too large.");
				}

				byte[] buffer = new byte[stream.Length];
				stream.Read(buffer, 0, (int)stream.Length);
				return buffer;
			}
		}

		/// <summary>
		/// Gets the bytes from URL.
		/// </summary>
		/// <param name="url">The URL.</param>
		/// <returns></returns>
		protected byte[] GetBytesFromUrl(Uri url)
		{
			// Open the url and attempt to read - this may fail...
			WebRequest request = WebRequest.Create(url);
			WebResponse response = request.GetResponse();
			if (response.ContentLength > 0)
			{
				if (response.ContentLength > 6000)
				{
					throw new InvalidOperationException("Content too large.");
				}

				int bytesRemaining = (int)response.ContentLength;
				byte[] buffer = new byte[bytesRemaining];
				int offset = 0;
				Stream stream = response.GetResponseStream();
				while (bytesRemaining > 0)
				{
					int bytesRead = stream.Read(buffer, offset, bytesRemaining);
					offset += bytesRead;
					bytesRemaining -= bytesRead;
				}

				return buffer;
			}
			return null;
		}

		/// <summary>
		/// Writes the content to the specified <see cref="StreamWriter"/>.
		/// </summary>
		/// <param name="writer">The writer.</param>
		protected abstract void WriteContentTo(StreamWriter writer);
	}
}
